#include "CppUTest/TestHarness.h"

extern "C"
{
#include "can/can_core.h"
#include "can_virtual.h"
#include "hdf_log.h"
}

#define TEST_CAN_BUS_NUM 31
#define TEST_CAN_BUS_NUM_INVALID 32

static int32_t VirtualCanSendMsg(struct CanCntlr *cntlr, const struct CanMsg *msg)
{
    (void)cntlr;
    (void)msg;
    return HDF_SUCCESS;
}

static int32_t VirtualCanSetCfg(struct CanCntlr *cntlr, const struct CanConfig *cfg)
{
    (void)cntlr;
    (void)cfg;
    return HDF_SUCCESS;
}

static int32_t VirtualCanGetCfg(struct CanCntlr *cntlr, struct CanConfig *cfg)
{
    (void)cntlr;
    (void)cfg;
    return HDF_SUCCESS;
}

struct CanCntlrMethod g_canMethod = {
    .sendMsg = VirtualCanSendMsg,
    .setCfg = VirtualCanSetCfg,
    .getCfg = VirtualCanGetCfg,
};

static struct CanCntlr g_cntlr;

TEST_GROUP(can_manager_test)
{
    void setup()
    {
        g_cntlr.number = TEST_CAN_BUS_NUM;
        g_cntlr.ops = &g_canMethod;
        LONGS_EQUAL(HDF_SUCCESS, CanCntlrAdd(&g_cntlr));
    }

    void teardown()
    {
        LONGS_EQUAL(HDF_SUCCESS, CanCntlrDel(&g_cntlr));
    }
};

TEST(can_manager_test, should_get_controller_by_number)
{
    struct CanCntlr *cntlr = NULL;

    cntlr = CanCntlrGetByNumber(TEST_CAN_BUS_NUM);
    CHECK_FALSE(cntlr == NULL);
    LONGS_EQUAL(TEST_CAN_BUS_NUM, cntlr->number);
    CanCntlrPut(cntlr);
};

TEST(can_manager_test, should_get_controller_by_name)
{
    struct CanCntlr *cntlr = NULL;

    cntlr = CanCntlrGetByName("CAN31");
    CHECK_FALSE(cntlr == NULL);
    LONGS_EQUAL(TEST_CAN_BUS_NUM, cntlr->number);
    CanCntlrPut(cntlr);
};
TEST(can_manager_test, should_not_harm_when_add_and_del_null_obj)
 {
    LONGS_EQUAL(HDF_ERR_INVALID_OBJECT, CanCntlrAdd(NULL));
    g_cntlr.ops = NULL;
    LONGS_EQUAL(HDF_ERR_INVALID_OBJECT, CanCntlrAdd(&g_cntlr));
    g_cntlr.ops = &g_canMethod;
    g_cntlr.number = -1;
    LONGS_EQUAL(HDF_ERR_INVALID_OBJECT, CanCntlrAdd(&g_cntlr));
    g_cntlr.number = TEST_CAN_BUS_NUM_INVALID;
    LONGS_EQUAL(HDF_ERR_INVALID_OBJECT, CanCntlrAdd(&g_cntlr));

    LONGS_EQUAL(HDF_ERR_INVALID_OBJECT, CanCntlrDel(NULL));
};
